import { ref, reactive } from 'vue'
import ChatView from '@/views/chat-view/chat-view.vue'

interface RouteMeta {
    title?: string;

    [key: string]: any;
}

interface RouteRecord {
    path: string;
    name: string;
    component: any;
    meta: RouteMeta;
}

interface ROUTER_OPTION {
    path?: string;
    name?: string;
    params?: Record<string, any>;
    query?: Record<string, any>;
}

interface RouteLocation {
    path: string;
    name: string;
    params: Record<string, any>;
    query: Record<string, any>;
    meta: RouteMeta;
    matched: RouteRecord[];
}

const routers: RouteRecord[] = [
    {
        path: '/',
        name: 'Chat',
        component: ChatView,
        meta: {
            title: 'MateChat 首页',
        },
    },
    {
        path: '/agent',
        name: 'Agent',
        component: () => import('@/views/agent-view/agent-view.vue'),
        meta: {
            title: 'MateChat 智能体',
        },
    },
    {
        path: '/prompt',
        name: 'Prompt',
        component: () => import('@/views/prompt-view/prompt-view.vue'),
        meta: {
            title: 'MateChat 提示词',
        },
    },
]

class Router {
    private routes: RouteRecord[]
    private pathMap: Map<string, RouteRecord>
    private nameMap: Map<string, RouteRecord>
    public beforeEach: (to: RouteLocation, from: RouteLocation, next: (path?: ROUTER_OPTION | boolean) => void) => void
    public afterEach: (to: RouteLocation, from: RouteLocation) => void

    // 响应式当前路由状态
    public currentRoute = reactive<RouteLocation>({
        path: '/',
        name: '',
        params: {},
        query: {},
        meta: {},
        matched: [],
    })

    // 当前显示的组件
    public currentComponent = ref<any>(null)

    constructor(routes: RouteRecord[]) {
        this.routes = routes
        this.pathMap = new Map()
        this.nameMap = new Map()

        // 初始化路由映射
        routes.forEach(route => {
            this.pathMap.set(route.path, route)
            this.nameMap.set(route.name, route)
        })

        // 默认守卫实现
        this.beforeEach = (to, from, next) => next()
        this.afterEach = () => {
        }

        // 设置初始路由
        this.push({path: '/'})
    }

    private async resolveRoute(options: ROUTER_OPTION): Promise<RouteLocation> {
        let matched: RouteRecord | undefined

        if (options.path) {
            matched = this.pathMap.get(options.path)
        } else if (options.name) {
            matched = this.nameMap.get(options.name)
        }

        if (!matched) {
            throw new Error(`Route not found: ${options.path || options.name}`)
        }

        // 加载组件（如果是异步组件）
        let component = matched.component
        if (typeof component === 'function') {
            try {
                component = (await component()).default
            } catch (e) {
                console.error(`Failed to load component for route: ${matched!.path}`, e)
            }
        }

        return {
            path: matched.path,
            name: matched.name,
            params: options.params || {},
            query: options.query || {},
            meta: {...matched.meta},
            matched: [matched],
        }
    }

    public async push(options: ROUTER_OPTION) {
        const from = {...this.currentRoute}
        const to = await this.resolveRoute(options)

        // 执行路由守卫
        await new Promise<void>((resolve, reject) => {
            this.beforeEach(to, from, (nextArg) => {
                if (nextArg === false) {
                    reject(new Error('Navigation aborted'))
                } else if (typeof nextArg === 'object') {
                    this.push(nextArg).then(resolve).catch(reject)
                } else {
                    resolve()
                }
            })
        })

        // 更新当前路由状态
        Object.assign(this.currentRoute, to)

        // 更新当前组件
        const matchedRecord = to.matched[0]
        if (typeof matchedRecord.component === 'function') {
            this.currentComponent.value = (await matchedRecord.component()).default
        } else {
            this.currentComponent.value = matchedRecord.component
        }

        // 更新文档标题
        if (to.meta.title) {
            document.title = to.meta.title
        }

        // 执行后置钩子
        this.afterEach(to, from)
    }

    // 提供 Vue 插件安装方法
    public install(app: any) {
        app.config.globalProperties.$router = this
        app.config.globalProperties.$route = this.currentRoute

        app.provide('router', this)
        app.provide('route', this.currentRoute)
    }
}

// 创建并导出路由实例
const router = new Router(routers)
export default router